package com.thientan.service

import com.thientan.export.ExportRequest
import com.thientan.model.HopDong
import com.thientan.model.ThongKePhieuThu
import com.thientan.model.enums.TrangThaiHopDong
import com.thientan.utils.Utility

class ThongKePhieuThuService extends AbstractService {
	@Override
	protected Long[] getColWidth() {
		return [80, 90, 100, 110, 110, 85, 105] as Long[]
	}

	@Override
	protected String[] getColTitles() {
		return [
			"Ngày lập",
			"Số phiếu nhận",
			"Số phiếu trả hết",
			"Số phiếu trả hàng",
			"Số phiếu đền hàng",
			"Số phiếu giao",
			"Tổng số phiếu còn lại ở công ty"] as String[]
	}

	@Override
	protected String[] getColNames() {
		return [
			"ngayLapText",
			"soPhieuNhan",
			"soPhieuTraHet",
			"soPhieuTraHang",
			"soPhieuDenHang",
			"soPhieuGiao",
			"soPhieuCty"] as String[]
	}

	@Override
	@SuppressWarnings("rawtypes")
	protected Class<?>[] getExportColType() {
		return [
			String.class,
			BigDecimal.class,
			BigDecimal.class,
			BigDecimal.class,
			BigDecimal.class,
			BigDecimal.class,
			BigDecimal.class] as Class<?>[]
	}

	@Override
	void prepareParametersBeforeExport(ExportRequest er){
		er.addParameter("ngayXuat", this.exportData?.ngayXuat)
		er.addParameter("thoiGian", this.exportData?.thoiGian)
	}

	/**
	 * Check if exist a ThongKePhieuThu in DB, else create a new instance.
	 * @return
	 */
	ThongKePhieuThu fetchOrCreateThongKePt() {
		ThongKePhieuThu object = ThongKePhieuThu.findByNgayLap(Utility.dateWithoutTime())
		return object ?: new ThongKePhieuThu(soPhieuCty : findSoPhieuCty(), soPhieuNhan : findNewHdCreatedInCurrentDay())
	}

	/**
	 * Update ThongKePhieuThu based on cases: giaoPhieuThu on TimHopDong and NhapPhieuThu
	 * @param tkpt
	 * @param hd The HopDong which be input data on NhapPhieuThu feature, if null means GiaoPhieuThu
	 * @return
	 */
	ThongKePhieuThu updateThongKePhieuThu(ThongKePhieuThu tkpt, HopDong hd, Long numHd = 1, Date previousDaGiaoPhieu) {
		if (!hd) {
			tkpt.soPhieuGiao += numHd
			tkpt.soPhieuCty -= numHd
		} else {
			switch (hd.trangThai) {
				case TrangThaiHopDong.DANG_TRA_GOP:
				break
				case TrangThaiHopDong.KET_THUC:
				tkpt.soPhieuTraHet += numHd
				break
				case TrangThaiHopDong.TRA_HANG:
				tkpt.soPhieuTraHang += numHd
				break
				case TrangThaiHopDong.DEN_HANG:
				tkpt.soPhieuDenHang += numHd
				break
				case TrangThaiHopDong.KHO_THU:
				break
			}
			// Only update thongke whenever daGiaoPhieu != null
			// In case nhanvien update chitietthuchi of hopdong several time, no need to increase number in thongke
			if (previousDaGiaoPhieu != null) {
				tkpt.soPhieuNhan += numHd
				tkpt.soPhieuCty += numHd
			}
		}
		ThongKePhieuThu savedTkpt = saveOrUpdate(tkpt)
		return savedTkpt ?: tkpt
	}

	/**
	 * Find the number of PhieuThu which company is holding (daGiaoPhieu is false or not assign to thuNgan)
	 * @return
	 */
	Long findSoPhieuCty() {
		HopDong.withNewSession { // Prevent flush operation
			List data = HopDong.withCriteria {
				projections { count("id") }
				eq("trangThai", TrangThaiHopDong.DANG_TRA_GOP)
				or {
					isNull("nvThuNgan")
					eq("daGiaoPhieu", null)
				}
			}
			data ? data.first() : 0
		}
	}
	
	Long findNewHdCreatedInCurrentDay() {
		Date currentDay = Utility.dateWithoutTime()
		HopDong.withNewSession { // Prevent flush operation
			List data = HopDong.withCriteria {
				projections { count("id") }
				eq("trangThai", TrangThaiHopDong.DANG_TRA_GOP)
				between("ngayBan", currentDay, Utility.increaseDays(currentDay))
			}
			data ? data.first() : 0
		}
	}
}
